#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtOpenGL>
#include <QyDebug.h>
#include <QyGLObject.h>
#include "QyTexturePool.h"

/**************************************************************************************************/

inline QString completeSlash( const QString & path ) {

    if ( path.isEmpty() )
        return path;

    return ( path[ path.count() - 1 ] == '/' ) ? path : path + "/";
}

/**************************************************************************************************/

QyTexturePool::QyTexturePool( const QString & path ) : glWidget(0) {

    if ( path.count() )
        loadFrom(path);

}

QyTexturePool::~QyTexturePool() {

    foreach ( QyGL::Texture * texture, textures ) {

        if ( GLuint texId = texture->textureId() )
            glDeleteTextures( 1, &texId );

        delete texture;

    }

}

bool QyTexturePool::loadFrom( const QString & path ) {

//     if ( path.isEmpty() )
//         return;

    QDir dir( QFileInfo(path).isRelative() ? completeSlash(basePath) + path : path );
//     QDir dir( completeSlash(basePath) + path );

    QStringList filter = QString("*.png;*.gif;*.jpg;*.jpeg").split(";");

    if ( dir.exists() ) {

//         qDebug( "QyTexturePool: Scan dir %s", qPrintable( dir.path() ) );
        foreach ( QFileInfo fileInfo, dir.entryInfoList(QDir::AllEntries|QDir::NoDotAndDotDot) ) {

//             QyDbgValue( fileInfo.absoluteFilePath() );

            if ( fileInfo.isFile() && QDir::match( filter, fileInfo.absoluteFilePath() ) )
                loadFile( fileInfo.absoluteFilePath() );
            else if ( fileInfo.isDir() )
                loadFrom( fileInfo.absoluteFilePath() );

        }

        return true;
    } else {

        qWarning( "QyTexturePool: Can't read from %s", qPrintable( dir.path() ) );

    }

    return false;
}

bool QyTexturePool::loadFile( const QString & filePath ) {

    if (!glWidget) {

        qWarning("QyTexturePool: Can't load texture. GLWidget not set");

        return false;
    }

    QString key = QDir(basePath).relativeFilePath(filePath);
//     qDebug( "QyTexturePool: load texture %s[%s]", qPrintable(filePath), qPrintable(key) );

    if ( textures.contains(key) ) {

        if ( QyGL::Texture * texture = textures[key] ) {

            qWarning( "QyTexturePool: Replace texture %s", qPrintable(key) );

            if ( GLuint texId = texture->textureId() )
                glDeleteTextures( 1, &texId );

            delete textures[key];

        }

    }

    textures[key] = new QyGL::Texture( glWidget->bindTexture( QPixmap(filePath) ) );

//     qDebug( "tex id: %d", textures[key]->textureId() );

    return true;
}

void QyTexturePool::loadFiles( const QStringList & files ) {

    foreach ( QString file, files )
        loadFile(file);

}

QList<QyGL::Texture*> QyTexturePool::makeSet( const QStringList & keys ) {

    QList<QyGL::Texture*> textureSet;

    foreach ( QString key, keys ) {

        if ( textures.contains(key) )
            textureSet.append(textures[key]);

    }

    return textureSet;
}

/*static */QyTexturePool * QyTexturePool::staticPool() {

    static QyTexturePool staticTexturePool;

    return &staticTexturePool;
}
